package com.inspire.server.netty;

import com.inspire.common.netty.MsgDecoder;
import com.inspire.common.netty.MsgEncoder;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.util.concurrent.GlobalEventExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author ：inspire
 * @date ：Created in 2022/8/12 14:09
 * @description：
 * @modified By：inspire
 * @version:
 */
public class Server {
    private static final Logger logger = LoggerFactory.getLogger(Server.class);

    public static ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    public void serverStart() {
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup(2);

        try {
            ServerBootstrap b = new ServerBootstrap(); 
            ChannelFuture f = b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .handler(new LoggingHandler(LogLevel.INFO))
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pl = ch.pipeline();
//                            pl.addLast(new MsgEncoder());
//                            pl.addLast(new MsgDecoder());
                            pl.addLast(new ServerChildHandler());
                            pl.addLast(new LoggingHandler(LogLevel.INFO));
                        }
                    })
                    .bind(8888)
                    .sync();

            logger.info("server started!");

            f.channel().closeFuture().sync(); //close()->ChannelFuture
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }
}
class ServerChildHandler extends ChannelInboundHandlerAdapter { //SimpleChannleInboundHandler Codec
    private static final Logger logger = LoggerFactory.getLogger(ServerChildHandler.class);

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Server.clients.add(ctx.channel());
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //ServerFrame.INSTANCE.updateClientMsg(msg.toString());
        logger.info("aaa"+msg.toString());

        Server.clients.writeAndFlush(msg);

		/*ByteBuf buf = null;
		try {
			buf = (ByteBuf)msg;

			byte[] bytes = new byte[buf.readableBytes()];
			buf.getBytes(buf.readerIndex(), bytes);
			String s = new String(bytes);

			if(s.equals("_bye_")) {
				System.out.println("");
				Server.clients.remove(ctx.channel());
				ctx.close();
			} else {
				Server.clients.writeAndFlush(msg);
			}*/

        //System.out.println(buf);
        //System.out.println(buf.refCnt());
		/*} finally {
			//if(buf != null && buf) ReferenceCountUtil.release(buf);
			//System.out.println(buf.refCnt());
		}*/
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        Server.clients.remove(ctx.channel());
        ctx.close();
    }


}
